package com.ckr.config;

import com.ckr.pojo.User;
import com.ckr.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author Shadowckr
 * @create 2022-01-17 12:22
 */

//自定义Realm
public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;

    //执行授权逻辑
    /*
    问题，我们现在完全是硬编码，无论是谁登录上来，都可以实现授权通过，但是真实的业务情况应该
    是，每个用户拥有自己的一些权限，从而进行操作，所以说，权限，应该在用户的数据库中，正常的情
    况下，数据库中是由一个权限表的，我们需要联表查询，但是这里为了大家操作理解方便一些，我
    们直接在数据库表中增加一个字段来进行操作！
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了=>授权逻辑doGetAuthorizationInfo");

        //给资源进行授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //添加资源的授权字符串
//        info.addStringPermission("user:add");

        //获得当前用户对象
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal();
        //设置当前用户的权限
        if (currentUser.getPerms() != null) {
            info.addStringPermission(currentUser.getPerms());
        } else {
            info.addStringPermission("unauthorized");
        }

        return info;
    }

    //执行认证逻辑
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了=>认证逻辑doGetAuthenticationInfo");

        //假设数据库的用户名和密码
//        String name = "root";
//        String password = "123456";

        //1.判断用户名
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

        //真实连接数据库
        User user = userService.queryUserByName(userToken.getUsername());
        if (user == null) {
            //用户名不存在
            return null;
        }

        Subject subject = SecurityUtils.getSubject();
        subject.getSession().setAttribute("loginUser", user);

//        if (!userToken.getUsername().equals(name)) {
//            //用户名不存在
//            return null; //shiro底层就会抛出 UnknownAccountException
//        }

        //2.验证密码，我们可以使用一个AuthenticationInfo实现类SimpleAuthenticationInfo
        // shiro会自动帮我们验证！重点是第二个参数就是要验证的密码！
//        return new SimpleAuthenticationInfo("", password, "");
        // 密码可以加密: md5加密，md5盐值加密
        // 获取登录的用户。在用户登录授权的时候，将用户放在 Principal 中。认证里传入user，即可以在授权那里拿到user。
        return new SimpleAuthenticationInfo(user, user.getPassword(), "");
    }

}
